home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Tech Arsenal 1
/
Tech Arsenal (Arsenal Computer).ISO
/
tek-01
/
neuron.zip
/
NETWORK.C
< prev
next >
Wrap
C/C++ Source or Header
|
1992-07-06
|
21KB
|
736 lines
/* Using NEURON.C for a simple neural network */
/* TC 2.0 E.FARHI */
/* versions: 1.0 10/91 Multi-layer net
2.0 11/91 First multi-model net
2.1 01/92 learn opt
2.2 03/92 simulated tempering
2.3 05/92 verify learning,
solving memory problems,
error handling */
/* ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
/* VERSION 2.3 */
/* ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
/* modules import ----------------------------------- */
#include <stdio.h> /* for printf */
#include <process.h> /* for system */
#include "neuron.c" /* computation module , how nice */
#include "savenet.c" /* Disk network utilities */
/* used procedures and functions -------------------------- */
/* coming from NEURON.C */
extern float sqr(float);
extern int *list_norm(int);
extern int *list_alea(int,int);
extern float network_state(NETWORKS *,float[]);
extern void init_alea_network(NETWORKS *);
extern void init_0_network(NETWORKS *);
extern void init_flag_network(NETWORKS *,int,int,int,int);
extern void init_var_network(NETWORKS *,float,float,float,float,float,float,float,float,float,float,float,float,float,float);
extern int learn_opt(NETWORKS *,int[],int,float[],float[]);
extern int learn_norm(NETWORKS *,int[],int,float[],float[]);
extern float learn_list(NETWORKS *,int[],int,float[],float[]);
extern int learn_test(NETWORKS *,int,long,long);
extern float sqr_sum(NETWORKS *);
extern float compare_output(NETWORKS *,float[]);
extern void print_network(NETWORKS *);
extern void info_struct_network(NETWORKS *);
extern void info_vars_network(NETWORKS *);
extern float learn_verify(NETWORKS *,int[],int,float[],float[]);
/* comming from SAVENET.C */
extern NETWORKS *load_network(char);
extern int save_network(NETWORKS *,char);
/* ------------------------------------------------------------ */
void main(void);
void print_output(NETWORKS *);
void vector_modify(float[],int,float,float); /* changes 0 and -1 */
void sort(float[],int[],int);
void print_result(NETWORKS *); /* print results !! */
void print_input(int,int,float[]);
void init_std_network(NETWORKS *);
int learn(NETWORKS *,int[],int,float[],float[],long,long);
int verif(NETWORKS *,int[],int,float[],float[]);
/* ----------------------------------------------------------- */
void print_output(NETWORKS *network)
{
int neuron,layer;
printf("\n-- Network output --\n");
layer=(*network).layer_order[(*network).nb_levels]; /* output */
for (neuron=0; neuron<=(*network).nb_n_layer[layer]; neuron++)
printf("Neuron No : %3i Output : %4.3f\n",neuron,(*network).neuron[neuron][layer].state);
printf("-----------------------\n\n");
}
void vector_modify(float vector[],int size,float high,float low)
{
int i;
float x;
for (i=1; i<=size; i++)
{
x=vector[i-1];
if (x==0) x=low;
else
if (x==1) x=high;
vector[i-1]=x;
}
}
void sort(float v[],int order[],int n) /* tri d'un tableau reel */
{ /* sends back a sorted array and its order */
int gap,i,j;
float temp;
for (gap=n/2; gap>0; gap/=2)
for (i=gap; i<=n; i++)
for (j=i-gap; j>=0 && v[j]>v[j+gap]; j-=gap)
{
temp=v[j]; /* ascending sort */
v[j]=v[j+gap];
v[j+gap]=temp;
temp=order[j];
order[j]=order[j+gap];
order[j+gap]=temp;
}
}
void print_input(int X,int Y,float input[])
{
int i,j;
printf("\nInput print :");
for (i=0; i<=Y; i++)
{
printf("\n");
for (j=0; j<=X; j++)
printf("%5.1f",input[i*X+j]);
}
printf("\n");
getchar();
}
void print_result(NETWORKS *network)
{ /* gives the global analysed output */
float v[NB_N_LAYER_MAXI];
int order[NB_N_LAYER_MAXI];
int layer,neuron,n_out,i;
float percent,percent_m=0,state;
char letter;
printf("\n------------- Network Output --------------\n");
layer=(*network).layer_order[(*network).nb_levels]; /* output */
n_out=(*network).nb_n_layer[layer];
for (neuron=0; neuron<=n_out; neuron++)
v[neuron]=fabs((*network).neuron[neuron][layer].state-(*network).high_state*(*network).coef_out);
for (i=0; i<=n_out; i++)
order[i]=i;
sort(v,order,n_out);
printf("\nAnalyze of results...\n");
for (i=n_out; i>=0; i--)
{
percent=(1-v[i]/((*network).high_state-(*network).low_state))*100;
letter='A'+order[i];
percent_m+=percent;
printf("\nLetter %c recognized at %3.1f %%. (state %4.2f)",letter,percent,(*network).neuron[order[i]][layer].state);
}
percent_m/=n_out+1;
percent=(1-v[0]/((*network).high_state-(*network).low_state))*100;
if (percent_m/percent<0.8)
{
letter='A'+order[0];
state=(*network).neuron[order[0]][layer].state;
printf("\n\nI recognize a %c at %3.1f %%. (state : %2.2f)",letter,percent,state);
}
else
printf("\n\nHard ! I can hardly identify your symbol !");
if (state<0)
printf("\n but, you are aware that it's not very clear...");
if (n_out>0)
{
percent_m=(1-v[1]/((*network).high_state-(*network).low_state))*100;
if (percent>2*percent_m)
printf("\n And I'm very proud of it...");
}
printf("\n\n <RETURN>");
getchar();
}
void init_std_network(NETWORKS *network)
{ /* initialize a standard network */
int i;
int activity=1; /* all active */
int interconnection=0; /* multi-perceptron */
int bias=0; /* no bias sur potentiel */
char tempering=TEMPERING_ON; /* simulated tempering */
float t_tempering_max=30; /* tempering temperatures */
float t_tempering_min=0;
float cte_tempering=10; /* exp decreasing cte */
/* -------- vars -------- */
float err_threshold=0.04; /* % for learning end test */
float beta=1; /* probabilistic neuron if beta<0 */
float coefficient=0.3; /* not too important to avoid oscillations */
float coef_out=0.9; /* coef for continuum neuron */
float high_threshold=0; /* potential boundaries */
float low_threshold;
float weight_threshold=20; /* weight boundaries */
float threshold=0;
float noise=0.1; /* % for noise */
float high_state=1;
float low_state=-1;
for (i=0; i<=(*network).nb_layers; i++)
if (high_threshold<(*network).nb_n_layer[i]+1)
high_threshold=(*network).nb_n_layer[i]+1;
high_threshold*=4;
low_threshold=-high_threshold;
init_var_network(network,err_threshold,beta,coefficient,coef_out,high_threshold,low_threshold,weight_threshold,threshold,noise,high_state,low_state,t_tempering_max,t_tempering_min,cte_tempering);
init_flag_network(network,activity,interconnection,bias,tempering);
init_alea_network(network);
}
int learn(NETWORKS *network,int *list_prototypes,int long_list,
float inputs[],float outputs[],long sizein,long sizeout)
{
int n=0,i;
float err=0;
printf("\nMaximal selected error : %3.1f (%%)",
(*network).err_threshold/(*network).nb_n_layer[(*network).layer_order[(*network).nb_levels]]*100);
do
{
printf("\nType in the maximal error you want (%%) :");
scanf("%4f",&err);
}
while ((err<0) || (err>100));
err/=100;
init_var_network(network,err,(*network).beta,(*network).coefficient,(*network).coef_out,
(*network).high_threshold,(*network).low_threshold,(*network).weight_threshold,(*network).threshold,(*network).noise,
(*network).high_state,(*network).low_state,(*network).t_tempering_max,(*network).t_tempering_min,(*network).cte_tempering);
info_struct_network(network);
info_vars_network(network);
printf("\nI begin to learn ...\n\n");
if (learn_test(network,long_list,sizein,sizeout))
do
{
i=learn_opt(network,list_prototypes,long_list,inputs,outputs);
if (i<0)
{
printf("\n Sorry, I can't memorize everything !");
printf("\n You can make it again if you wish...");
i*=-1;
n+=i;
continue;
}
n+=i;
}
while(verif(network,list_prototypes,long_list,inputs,outputs));
else
{
printf("I can't learn those prototypes");
return(0);
}
printf("\nThere were %3i learning turns.\n\a",n);
printf("\n <RETURN>");getchar();
return(n);
}
int verif(NETWORKS *network,int *list_prototypes,int long_list,float inputs[],float outputs[])
{
float err;
printf("\n\nLearning verification");
err=learn_verify(network,list_prototypes,long_list,inputs,outputs);
printf("\n\nMaximal error: %4.2f",err);
return(err>(*network).err_threshold);
}
NETWORKS *network;
/* ------------------------------------------------------------ */
/* network definition */
/* ------------------------------------------------------------ */
/* definition of the structure -------- */
int nb_layers=2; /* size */
int nb_levels=2;
int nb_n_layer[]={34,19,25};
int layer_order[]={0,1,2};
/* The prototypes ----------------------------------- */
/* NOTE: For the data input, we used:
state 1 active (high_state)
state 0 inactive(low_state)
It enables an easier reading of protytpes.
The function 'vector_modify' sets the prototypes for
the module 'neuron.c' ... */
int nb_prototypes_tot=29; /* number of prototypes to learn */
float inputs[]={ /* All prototype inputs */
0,1,1,1,0, /* Inputs are */
1,0,0,0,1, /* 5*7 digitalized caracters */
1,0,0,0,1,
1,1,1,1,1,
1,0,0,0,1, /* This is the alphabet of the*/
1,0,0,0,1, /* HP 28S */
1,0,0,0,1,
1,1,1,1,0,
1,0,0,0,1,
1,0,0,0,1,
1,1,1,1,0,
1,0,0,0,1,
1,0,0,0,1,
1,1,1,1,0,
0,1,1,1,0,
1,0,0,0,1,
1,0,0,0,0,
1,0,0,0,0,
1,0,0,0,0,
1,0,0,0,1,
0,1,1,1,0,
1,1,1,0,0,
1,0,0,1,0,
1,0,0,0,1,
1,0,0,0,1,
1,0,0,0,1,
1,0,0,1,0,
1,1,1,0,0,
1,1,1,1,1,
1,0,0,0,0,
1,0,0,0,0,
1,1,1,1,0,
1,0,0,0,0,
1,0,0,0,0,
1,1,1,1,1,
1,1,1,1,1,
1,0,0,0,0,
1,0,0,0,0,
1,1,1,1,0,
1,0,0,0,0,
1,0,0,0,0,
1,0,0,0,0,
0,1,1,1,0,
1,0,0,0,1,
1,0,0,0,0,
1,0,0,0,0,
1,0,0,1,1,
1,0,0,0,1,
0,1,1,1,0,
1,0,0,0,1,
1,0,0,0,1,
1,0,0,0,1,
1,1,1,1,1,
1,0,0,0,1,
1,0,0,0,1,
1,0,0,0,1,
1,1,1,1,1,
0,1,1,1,0,
0,1,1,1,0,
0,1,1,1,0,
0,1,1,1,0,
0,1,1,1,0,
1,1,1,1,1,
0,0,0,0,1,
0,0,0,0,1,
0,0,0,0,1,
0,0,0,0,1,
0,0,0,0,1,
1,0,0,0,1,
0,1,1,1,0,
1,0,0,0,1,
1,0,0,0,1,
1,0,0,1,0,
1,1,1,0,0,
1,0,0,1,0,
1,0,0,0,1,
1,0,0,0,1,
1,0,0,0,0,
1,0,0,0,0,
1,0,0,0,0,
1,0,0,0,0,
1,0,0,0,0,
1,0,0,0,0,
1,1,1,1,1,
1,0,0,0,1,
1,1,0,1,1,
1,0,1,0,1,
1,0,0,0,1,
1,0,0,0,1,
1,0,0,0,1,
1,0,0,0,1,
1,0,0,0,1,
1,0,0,0,1,
1,1,0,0,1,
1,0,1,0,1,
1,0,0,1,1,
1,0,0,0,1,
1,0,0,0,1,
0,1,1,1,0,
1,0,0,0,1,
1,0,0,0,1,
1,0,0,0,1,
1,0,0,0,1,
1,0,0,0,1,
0,1,1,1,0,
1,1,1,1,0,
1,0,0,0,1,
1,0,0,0,1,
1,1,1,1,0,
1,0,0,0,0,
1,0,0,0,0,
1,0,0,0,0,
0,1,1,1,0,
1,0,0,0,1,
1,0,0,0,1,
1,0,0,0,1,
1,0,1,0,1,
1,0,0,1,0,
0,1,1,0,1,
1,1,1,1,0,
1,0,0,0,1,
1,0,0,0,1,
1,1,1,1,0,
1,0,1,0,0,
1,0,0,1,0,
1,0,0,0,1,
0,1,1,1,0,
1,0,0,0,1,
1,0,0,0,0,
0,1,1,1,0,
0,0,0,0,1,
1,0,0,0,1,
0,1,1,1,0,
1,1,1,1,1,
0,0,1,0,0,
0,0,1,0,0,
0,0,1,0,0,
0,0,1,0,0,
0,0,1,0,0,
0,0,1,0,0,
1,0,0,0,1,
1,0,0,0,1,
1,0,0,0,1,
1,0,0,0,1,
1,0,0,0,1,
1,0,0,0,1,
0,1,1,1,0,
1,0,0,0,1,
1,0,0,0,1,
1,0,0,0,1,
1,0,0,0,1,
1,0,0,0,1,
0,1,0,1,0,
0,0,1,0,0,
1,0,0,0,1,
1,0,0,0,1,
1,0,0,0,1,
1,0,1,0,1,
1,0,1,0,1,
1,1,0,1,1,
1,0,0,0,1,
1,0,0,0,1,
1,0,0,0,1,
0,1,0,1,0,
0,0,1,0,0,
0,1,0,1,0,
1,0,0,0,1,
1,0,0,0,1,
1,0,0,0,1,
1,0,0,0,1,
0,1,0,1,0,
0,0,1,0,0,
0,0,1,0,0,
0,0,1,0,0,
0,0,1,0,0,
1,1,1,1,1,
0,0,0,0,1,
0,0,0,1,0,
0,0,1,0,0,
0,1,0,0,0,
1,0,0,0,0,
1,1,1,1,1,
0,0,1,0,0,
0,1,1,1,0,
0,1,0,1,0,
1,1,0,1,1,
1,1,1,1,1,
1,1,0,1,1,
1,0,0,0,1,
1,0,0,0,1,
0,1,0,0,1,
0,0,1,1,0,
0,0,1,1,0,
0,0,1,0,0,
0,1,0,0,0,
1,0,0,0,0,
1,0,0,0,1,
1,0,0,0,1,
1,0,1,0,1,
1,1,1,1,1,
1,1,1,1,1,
0,1,0,1,0,
0,1,0,1,0,
1,0,0,0,1,
1,0,0,0,1,
1,0,0,0,1,
1,1,0,1,1,
0,1,0,1,0,
0,1,1,1,0,
0,0,1,0,0
};
float outputs[]={ /* each caracter is associated to a neuron */
1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0
};
float input1[]= { /* a strange 'V': twilight zone... */
1,0,0,0,1,
1,0,0,0,1,
1,0,0,0,1,
1,0,0,0,1,
1,0,0,0,1,
0,1,0,1,0,
0,0,1,0,0 };
/* ************************************************************ */
void main(void)
{
/* used by 'main()' */
int long_list;
int n,*list_prototypes;
char flag='3',choice;
float h,l,coef;
/* -------------------------------------------------------------- */
network=(NETWORKS *)malloc(sizeof(NETWORKS)); /* allocating memory */
if (network == NULL) /* is there any room here ? */
{
printf("Not enough memory. Sorry NetWork too large");
exit (-1);
}
/* transfering structure data */
(*network).nb_layers=nb_layers;
(*network).nb_levels=nb_levels;
for (n=0; n<=nb_layers; n++)
(*network).nb_n_layer[n]=nb_n_layer[n];
for (n=0; n<=nb_levels; n++)
(*network).layer_order[n]=layer_order[n];
/* initialization of network ----------------------------------- */
printf("\nWe initialize the network ...\n");
init_std_network(network);
/* preparing learning --------------------------------------- */
printf("\n\nPreparation of prototypes for learning\n");
/* prepare prototypes */
h=(*network).high_state;
l=(*network).low_state;
coef=(*network).coef_out;
vector_modify(inputs,(int)(sizeof(inputs)/sizeof(float)),h,l);
vector_modify(outputs,(int)(sizeof(outputs)/sizeof(float)),h*coef,l*coef);
vector_modify(input1,(int)(sizeof(input1)/sizeof(float)),h,l);
/* WARNING: for the outputs with continuum neurons continus you mustn't
impose the state boundaries in prototypes (state high and low accessible only if infinite potentiel !)
but some inferior states.
ex: for the states 1 et -1 -> 0.9 and -0.9 */
/* preparation of lists */
long_list=nb_prototypes_tot; /* we learn all prototypes */
list_prototypes=list_norm(long_list); /* normal list for learn_opt */
/* ------------------------ menu ------------------------------ */
do /* without end */
{
do /* menu */
{
printf("\n***************** MENU PRINCIPAL ******************");
printf("\n\n -> Enter your choice : ");
printf("\n\n0- Quit");
printf("\n\n1- Learning (default prototypes)");
printf("\n\n2- Load a network from disk");
printf("\n\n3- Listing of networks on disk");
if (flag == '5')
{
printf("\n\n4- Save the active network to disk");
printf("\n\n5- Caracter recognition(example...)");
}
printf("\n\nYour choice (+RETURN): ");
choice=getchar();
printf("%c",choice);
}
while((choice < '0') || (choice > flag));
switch(choice)
{
case '0':printf("\n\nHello world ! Bye!");getchar();
exit(0);
case '1':if (learn(network,list_prototypes,long_list,inputs,outputs,sizeof(inputs),sizeof(outputs)))
flag='5';
break;
case '2':printf("\nLoading network");
free(network);
network=load_network(NORMLOAD);
if (network == NULL)
{
printf("\n\aNetwork handling error");
flag='3';
}
else
{
flag='5';
info_struct_network(network);
info_vars_network(network);
if (verif(network,list_prototypes,long_list,inputs,outputs))
printf("\n You should proceed another learning...");
printf("\n <RETURN>");getchar();
}
break;
case '3':printf("\n");system("ls *.net");printf("\n\n <RETURN>");getchar();break;
case '4':printf("\nSaving network to disk");
save_network(network,NORMSAVE);
break;
case '5':printf("\n\aYou should do it!!!");
printf("\nHere is an example for a strange 'V'");
print_input(4,6,input1);
network_state(network,input1);
/* input1 contains of caracter, has been modified with
vector_modify */
print_result(network);
break;
default:printf("* Bug *");
} /* switch */
} /* do */
while(1);
} /* main */
/* --ooOO THE END OOoo-- */